<?php
namespace app\client\controller\pay;
use think\db\Expression;

class AppleController extends \think\Controller {
  const PRODUCT = [ // 干瞪眼
    'com.qshy.store.buy6'    => '6:60',  // 6元12个元宝
    'com.qshy.store.buy12'   => '12:120',
    'com.qshy.store.buy30'   => '30:300',
    'com.qshy.store.buy218'  => '218:2180',
    'com.qshy.store.buy518'  => '518:5180',
  ];
  /**
   *  @brief  : 苹果内购验证
   *  @return : json
   *  @details:
   *  http://cl.123pk123.com/apple/valid.html?receipt=&uid=
   */
  public function validAction() {

    trace($this->request->param());
    $receipt  = $this->request->param('receipt/s', '');
    $uid      = $this->request->param('uid/d', 0);

    if (empty($receipt) || $uid <= 0) {
      return result([], 100, '业务参数不能为空');
    }
    $eax = base64_decode($receipt);
    if (empty($eax)) {
      return result([], 101, '业务参数无效');
    }
    $url = (stripos($eax, 'Sandbox') !== false) ? 'https://sandbox.itunes.apple.com/verifyReceipt' : 'https://buy.itunes.apple.com/verifyReceipt';
    $user = table('AccountsInfo', 'rydb.accounts')->field(['UserID', 'GameID', 'Accounts', 'NickName'])->where(['UserID'=>$uid, 'AccountsType'=>0])->find();
    if(empty($user)){
      return result([], 102, '玩家不存在');
    }
    $eax = curl([
      CURLOPT_URL             => $url,
      CURLOPT_SSL_VERIFYHOST  => FALSE,
      CURLOPT_SSL_VERIFYPEER  => FALSE,
      CURLOPT_POSTFIELDS      => json_encode([
        'receipt-data'  => $receipt,
      ]),
    ]);
    if ($eax['errno'] != 0) {
      trace(['errno' => $eax['errno'], 'error' => $eax['error']]);
      return result([], 103, '网络异常');
    }

    $eax = json_decode($eax['data'], true);
    trace($eax);
    if ($eax['status'] != 0) {
      return result([], 104, '验证失败');
    }
    $receipt    = $eax['receipt'];
    $quantity   = $receipt['quantity'];
    $product_id = $receipt['product_id'];
    $transaction_id     = $receipt['transaction_id'];
    $unique_identifier  = $receipt['unique_identifier'];
    
    if (empty(self::PRODUCT[$product_id])) {
      return result([], 105, '产品ID未定义');
    }

    // 取出价格对应钻石数
    sscanf(self::PRODUCT[$product_id], '%d:%d', $RMB, $ZSS);
    $RMB = $quantity * $RMB;
    $ZSS = $quantity * $ZSS;

    // 判断表中有无该订单? 订单是否已到账?
    $charge = table('ChargeOnline', 'rydb.websms')->field(['ID','GameStatus'])->where([
      'GameID'=>$user['GameID'], 'UserID'=>$uid, 'MerBillNo'=>$transaction_id, 'PayType'=>'ios'
    ])->find();
    if (empty($charge)) { // 数据库中无该订单
      $chargeID = table('ChargeOnline', 'rydb.websms')->insertGetId([
        'UserID'    => $uid,
        'GameID'    => $user['GameID'],
        'Accounts'  => $user['Accounts'],
        'MerBillNo' => $transaction_id,
        'RMB'       => $RMB,
        'Addtime'   => new Expression('GETDATE()'),
        'Status'    => 1, // 1=支付成功; 0=未支付
        'PayType'   => 'ios',
        'wwwType'   => $this->request->server('SERVER_NAME/s', ''),
        'wwwIp'     => $this->request->ip(),
        'TradeNo'   => $unique_identifier,
      ]);
      if ($chargeID <= 0) {
        return result([], 106, '支付验证成功, 写入订单失败');
      }
    } else {  // 数据库中存在该订单
      if ($charge['GameStatus'] == 1) {
        return result([], 107, '支付验证成功, 订单已经到账');
      }
      $chargeID = $charge['ID'];
    }
    // 更新房卡数
    table('AccoutsGameCurrency', 'rydb.basic')->where('UserID', $uid)->setInc('RoomCard', $ZSS);  // 房卡数=钻石数
    table('AccoutsGameCurrency', 'rydb.basic')->where('UserID', $uid)->setInc('ChargeNum', $RMB);  
    $user2 = table('AccoutsGameCurrency', 'rydb.basic')->where('UserID', $uid)->find();
    // 更新订单
    table('ChargeOnline', 'rydb.websms')->where('ID', $chargeID)->update([
      'GameStatus'  => 1,
      'Updatetime'  => new Expression('GETDATE()'),
    ]);
    // 写入充值订单记录
    $eax = table('RecordRoomCard', 'rydb.record')->insertGetId([
      'SourceUserID'    => $uid,
      'RoomCard'        => $ZSS,
      'TypeID'          => 10,
      'ClientIP'        => $this->request->ip(),
      'CollectDate'     => new Expression('GETDATE()'),
      'Remarks'         => "充值{$RMB}元",
    ]);
    $RoomCard = $user2['RoomCard'];
    $eax2 = table('CostRoomCardRecord', 'rydb.record')->insertGetId([
    'dwUserID'        => $uid,
    'dwCost'          => $ZSS,
    'dwCostType'      => 10,  // 10=充值
    'beleftRoomCard'  => $RoomCard,  // 变动后余额
    'describe'        => "充值{$RMB}元，获得房卡{$ZSS}张，剩余房卡{$RoomCard}张",
    'CostTime'        => new Expression('GETDATE()'),
    ]);
    return result([], 0);
  }
  /*
  参考文档 https://developer.apple.com/library/archive/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html
  receipt->status
21000 The App Store could not read the JSON object you provided.
21002 The data in the receipt-data property was malformed or missing.
21003 The receipt could not be authenticated.
21004 The shared secret you provided does not match the shared secret on file for your account.
21005 The receipt server is not currently available.
21006 This receipt is valid but the subscription has expired. When this status code is returned to your server,
      the receipt data is also decoded and returned as part of the response.
      Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions.

21007 This receipt is from the test environment, but it was sent to the production environment for verification.
      Send it to the test environment instead.
21008 This receipt is from the production environment, but it was sent to the test environment for verification.
      Send it to the production environment instead.
21010 This receipt could not be authorized. Treat this the same as if a purchase was never made.
21100-21199 Internal data access error.
  */
}
